home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / Src / Ch12 / Hexes1.frm (.txt) < prev    next >
Visual Basic Form  |  1999-06-19  |  14KB  |  471 lines

  1. VERSION 5.00
  2. Begin VB.Form frmHexes1 
  3.    Caption         =   "Hexes1"
  4.    ClientHeight    =   3150
  5.    ClientLeft      =   2550
  6.    ClientTop       =   1800
  7.    ClientWidth     =   3150
  8.    LinkTopic       =   "Form1"
  9.    PaletteMode     =   1  'UseZOrder
  10.    ScaleHeight     =   3150
  11.    ScaleWidth      =   3150
  12.    Begin VB.HScrollBar HScrollBar 
  13.       Height          =   255
  14.       Left            =   0
  15.       TabIndex        =   2
  16.       Top             =   2880
  17.       Width           =   2895
  18.    End
  19.    Begin VB.VScrollBar VScrollBar 
  20.       Height          =   2895
  21.       Left            =   2880
  22.       TabIndex        =   1
  23.       Top             =   0
  24.       Width           =   255
  25.    End
  26.    Begin VB.PictureBox picCanvas 
  27.       Height          =   2880
  28.       Left            =   0
  29.       ScaleHeight     =   2820
  30.       ScaleWidth      =   2820
  31.       TabIndex        =   0
  32.       Top             =   0
  33.       Width           =   2880
  34.    End
  35.    Begin VB.Menu mnuFile 
  36.       Caption         =   "&File"
  37.       Begin VB.Menu mnuFileExit 
  38.          Caption         =   "E&xit"
  39.       End
  40.    End
  41.    Begin VB.Menu mnuScale 
  42.       Caption         =   "&Scale"
  43.       Begin VB.Menu mnuScaleZoom 
  44.          Caption         =   "&Zoom"
  45.          Shortcut        =   ^Z
  46.       End
  47.       Begin VB.Menu mnuScaleMag 
  48.          Caption         =   "Full  Scale"
  49.          Index           =   1
  50.          Shortcut        =   ^F
  51.       End
  52.       Begin VB.Menu mnuScaleMag 
  53.          Caption         =   "Magnify 1/2"
  54.          Index           =   20
  55.          Shortcut        =   ^{F2}
  56.       End
  57.       Begin VB.Menu mnuScaleMag 
  58.          Caption         =   "Magnify 1/4"
  59.          Index           =   40
  60.          Shortcut        =   ^{F4}
  61.       End
  62.    End
  63. Attribute VB_Name = "frmHexes1"
  64. Attribute VB_GlobalNameSpace = False
  65. Attribute VB_Creatable = False
  66. Attribute VB_PredeclaredId = True
  67. Attribute VB_Exposed = False
  68. Option Explicit
  69. ' All of the Hex objects.
  70. Private Hexes As Collection
  71. ' Global max and min world coordinates
  72. ' (including margins).
  73. Private DataXmin As Single
  74. Private DataXmax As Single
  75. Private DataYmin As Single
  76. Private DataYmax As Single
  77. ' Set the min and max allowed width and height.
  78. Private DataMinWid As Single
  79. Private DataMinHgt As Single
  80. Private DataMaxWid As Single
  81. Private DataMaxHgt As Single
  82. ' The aspect ratio of the viewport.
  83. Private VAspect As Single
  84. ' Current world window bounds.
  85. Private Wxmin As Single
  86. Private Wxmax As Single
  87. Private Wymin As Single
  88. Private Wymax As Single
  89. ' Prevent change events when we are adjusting the
  90. ' scroll bars.
  91. Private IgnoreSbarChange As Boolean
  92. ' Variables used for zooming.
  93. Private DrawingMode As Integer
  94. Const MODE_NONE = 0
  95. Const MODE_START_ZOOM = 1
  96. Const MODE_ZOOMING = 2
  97. Private StartX As Single
  98. Private StartY As Single
  99. Private LastX As Single
  100. Private LastY As Single
  101. Private OldMode As Integer
  102. ' The object that is highlighted.
  103. Private Selectedhex As Object
  104. ' Find the object at this point.
  105. Private Function ObjectAt(ByVal X As Single, ByVal Y As Single)
  106. Dim obj As Hex
  107.     Set ObjectAt = Nothing
  108.     For Each obj In Hexes
  109.         With obj
  110.             If obj.IsAt(X, Y) Then
  111.                 Set ObjectAt = obj
  112.                 Exit For
  113.             End If
  114.         End With
  115.     Next obj
  116. End Function
  117. ' End a zoom operation early. This happens if the
  118. ' user starts a zoom and the selects another menu
  119. ' item instead of doing the zoom.
  120. Private Sub StopZoom()
  121.     If DrawingMode <> MODE_START_ZOOM Then Exit Sub
  122.     DrawingMode = MODE_NONE
  123.     picCanvas.DrawMode = OldMode
  124.     picCanvas.MousePointer = vbDefault
  125. End Sub
  126. ' Change the level of magnification.
  127. Private Sub SetScaleFactor(fact As Single)
  128. Dim wid As Single
  129. Dim hgt As Single
  130. Dim mid As Single
  131.     fact = 1 / fact
  132.     ' Compute the new world window size.
  133.     wid = fact * (Wxmax - Wxmin)
  134.     hgt = fact * (Wymax - Wymin)
  135.     ' Center the new world window over the old.
  136.     mid = (Wxmax + Wxmin) / 2
  137.     Wxmin = mid - wid / 2
  138.     Wxmax = mid + wid / 2
  139.     mid = (Wymax + Wymin) / 2
  140.     Wymin = mid - hgt / 2
  141.     Wymax = mid + hgt / 2
  142.     ' Set the new world window bounds.
  143.     SetWorldWindow
  144. End Sub
  145. ' Adjust the world window so it is not too big,
  146. ' too small, off to one side, or of the wrong
  147. ' aspect ratio. Then map the world window to the
  148. ' viewport and force the viewport to repaint.
  149. Private Sub SetWorldWindow()
  150. Dim wid As Single
  151. Dim hgt As Single
  152. Dim xmid As Single
  153. Dim ymid As Single
  154. Dim aspect As Single
  155.     wid = Wxmax - Wxmin
  156.     xmid = (Wxmax + Wxmin) / 2
  157.     hgt = Wymax - Wymin
  158.     ymid = (Wymax + Wymin) / 2
  159.         
  160.     ' Make sure we're not too big or too small.
  161.     If wid > DataMaxWid Then
  162.         wid = DataMaxWid
  163.     ElseIf wid < DataMinWid Then
  164.         wid = DataMinWid
  165.     End If
  166.     If hgt > DataMaxHgt Then
  167.         hgt = DataMaxHgt
  168.     ElseIf hgt < DataMinHgt Then
  169.         hgt = DataMinHgt
  170.     End If
  171.     ' Make the aspect ratio match the
  172.     ' viewport aspect ratio.
  173.     aspect = hgt / wid
  174.     If aspect > VAspect Then
  175.         ' Too tall and thin. Make it wider.
  176.         wid = hgt / VAspect
  177.     Else
  178.         ' Too short and wide. Make it taller.
  179.         hgt = wid * VAspect
  180.     End If
  181.     ' Compute the new coordinates
  182.     Wxmin = xmid - wid / 2
  183.     Wxmax = xmid + wid / 2
  184.     Wymin = ymid - hgt / 2
  185.     Wymax = ymid + hgt / 2
  186.     ' Check that we're not off to one side.
  187.     If wid > DataMaxWid Then
  188.         ' We're wider than the picture. Center.
  189.         xmid = (DataXmax + DataXmin) / 2
  190.         Wxmin = xmid - wid / 2
  191.         Wxmax = xmid + wid / 2
  192.     Else
  193.         ' Else see if we're too far to one side.
  194.         If Wxmin < DataXmin And Wxmax < DataXmax Then
  195.             ' Adjust to the right.
  196.             Wxmax = Wxmax + DataXmin - Wxmin
  197.             Wxmin = DataXmin
  198.         End If
  199.         If Wxmax > DataXmax And Wxmin > DataXmin Then
  200.             ' Adjust to the left.
  201.             Wxmin = Wxmin + DataXmax - Wxmax
  202.             Wxmax = DataXmax
  203.         End If
  204.     End If
  205.     If hgt > DataMaxHgt Then
  206.         ' We're taller than the picture. Center.
  207.         ymid = (DataYmax + DataYmin) / 2
  208.         Wymin = ymid - hgt / 2
  209.         Wymax = ymid + hgt / 2
  210.     Else
  211.         ' See if we're too far to top or bottom.
  212.         If Wymin < DataYmin And Wymax < DataYmax Then
  213.             ' Adjust downward.
  214.             Wymax = Wymax + DataYmin - Wymin
  215.             Wymin = DataYmin
  216.         End If
  217.         If Wymax > DataYmax And Wymin > DataYmin Then
  218.             ' Adjust upward.
  219.             Wymin = Wymin + DataYmax - Wymax
  220.             Wymax = DataYmax
  221.         End If
  222.     End If
  223.     ' Map the world window to the viewport.
  224.     picCanvas.Scale (Wxmin, Wymax)-(Wxmax, Wymin)
  225.     ' Force the viewport to repaint.
  226.     picCanvas.Refresh
  227.         
  228.     ' Reset the scroll bars.
  229.     IgnoreSbarChange = True
  230.     HScrollBar.Visible = (wid < DataXmax - DataXmin)
  231.     VScrollBar.Visible = (hgt < DataYmax - DataYmin)
  232.     ' The values of the scroll bars will be where
  233.     ' the top/left of the world window should be.
  234.     VScrollBar.Min = 100 * (DataYmax)
  235.     VScrollBar.Max = 100 * (DataYmin + hgt)
  236.     HScrollBar.Min = 100 * (DataXmin)
  237.     HScrollBar.Max = 100 * (DataXmax - wid)
  238.     ' SmallChange moves the world window 1/10
  239.     ' of its width/height. Large change moves it
  240.     ' 9/10 of its width/height.
  241.     VScrollBar.SmallChange = 100 * (hgt / 10)
  242.     VScrollBar.LargeChange = 100 * (9 * hgt / 10)
  243.     HScrollBar.SmallChange = 100 * (wid / 10)
  244.     HScrollBar.LargeChange = 100 * (9 * wid / 10)
  245.     ' Set the current scroll bar values.
  246.     VScrollBar.Value = 100 * Wymax
  247.     HScrollBar.Value = 100 * Wxmin
  248.     IgnoreSbarChange = False
  249. End Sub
  250. ' Return to the default magnification scale.
  251. Private Sub SetScaleFull()
  252.     ' Reset the world window coordinates.
  253.     Wxmin = DataXmin
  254.     Wxmax = DataXmax
  255.     Wymin = DataYmin
  256.     Wymax = DataYmax
  257.     ' Set the new world window bounds.
  258.     SetWorldWindow
  259. End Sub
  260. Private Sub Form_Load()
  261.     MakeHexes
  262. End Sub
  263. Private Sub Form_Resize()
  264. Dim X As Single
  265. Dim Y As Single
  266. Dim wid As Single
  267. Dim hgt As Single
  268.     ' Fit the viewport to the window.
  269.     X = picCanvas.Left
  270.     Y = picCanvas.Top
  271.     wid = ScaleWidth - 2 * X - VScrollBar.Width
  272.     hgt = ScaleHeight - 2 * Y - HScrollBar.Height
  273.     picCanvas.Move X, Y, wid, hgt
  274.     VAspect = hgt / wid
  275.     ' Place the scroll bars next to the viewport.
  276.     X = picCanvas.Left + picCanvas.Width + 10
  277.     Y = picCanvas.Top
  278.     wid = VScrollBar.Width
  279.     hgt = picCanvas.Height
  280.     VScrollBar.Move X, Y, wid, hgt
  281.     X = picCanvas.Left
  282.     Y = picCanvas.Top + picCanvas.Height + 10
  283.     wid = picCanvas.Width
  284.     hgt = HScrollBar.Height
  285.     HScrollBar.Move X, Y, wid, hgt
  286.     ' Start at full scale.
  287.     SetScaleFull
  288. End Sub
  289. ' Make the Hexes.
  290. Private Sub MakeHexes()
  291. Const NUM_ROWS = 50
  292. Const NUM_COLS = 50
  293. Dim new_hex As Hex
  294. Dim i As Integer
  295. Dim j As Integer
  296. Dim X As Single
  297. Dim Y As Single
  298. Dim wid As Single
  299. Dim hgt As Single
  300.     MousePointer = vbHourglass
  301.     DoEvents
  302.     Set Hexes = New Collection
  303.     Y = 0
  304.     For i = 1 To NUM_ROWS
  305.         X = 0
  306.         For j = 1 To NUM_COLS
  307.             Set new_hex = New Hex
  308.             Hexes.Add new_hex
  309.             new_hex.Cx = X
  310.             new_hex.Cy = Y
  311.             new_hex.Radius = 0.4
  312.             X = X + 2
  313.         Next j
  314.         Y = Y + 2
  315.     Next i
  316.     wid = 2 * NUM_COLS + 1
  317.     hgt = 2 * NUM_ROWS + 1
  318.     DataXmin = -0.1 * wid   ' 10 % margins.
  319.     DataYmin = -0.1 * hgt
  320.     DataXmax = 1.1 * wid
  321.     DataYmax = 1.1 * hgt
  322.     DataMinWid = 10
  323.     DataMinHgt = 10
  324.     DataMaxWid = DataXmax - DataXmin
  325.     DataMaxHgt = DataYmax - DataYmin
  326.     MousePointer = vbDefault
  327. End Sub
  328. ' Move the world window.
  329. Private Sub HScrollBar_Change()
  330.     If IgnoreSbarChange Then Exit Sub
  331.     HScrollBarChanged
  332. End Sub
  333. ' The vertical scroll bar has been moved. Adjust
  334. ' the world window.
  335. Private Sub VScrollBarChanged()
  336. Dim hgt As Single
  337.     hgt = Wymax - Wymin
  338.     Wymax = VScrollBar.Value / 100
  339.     Wymin = Wymax - hgt
  340.     ' Remap the world window.
  341.     IgnoreSbarChange = True
  342.     SetWorldWindow
  343.     IgnoreSbarChange = False
  344. End Sub
  345. ' The horizontal scroll bar has been moved. Adjust
  346. ' the world window.
  347. Private Sub HScrollBarChanged()
  348. Dim wid As Single
  349.     wid = Wxmax - Wxmin
  350.     Wxmin = HScrollBar.Value / 100
  351.     Wxmax = Wxmin + wid
  352.     ' Remap the world window.
  353.     IgnoreSbarChange = True
  354.     SetWorldWindow
  355.     IgnoreSbarChange = False
  356. End Sub
  357. Private Sub mnuFileExit_Click()
  358.     StopZoom    ' If we're zooming, stop it.
  359.     Unload Me
  360. End Sub
  361. ' Change the level of magnification.
  362. Private Sub mnuScaleMag_Click(Index As Integer)
  363.     StopZoom    ' If we're zooming, stop it.
  364.     If Index = 1 Then
  365.         ' Return to full scale.
  366.         SetScaleFull
  367.     ElseIf Index < 10 Then
  368.         ' Magnify by the indicated amount.
  369.         SetScaleFactor CSng(Index)
  370.     Else
  371.         ' Zoom out by 1/(Index \ 10).
  372.         SetScaleFactor 1 / (Index \ 10)
  373.     End If
  374. End Sub
  375. ' Allow the user to select an area to zoom in on.
  376. Private Sub mnuScaleZoom_Click()
  377.     ' Enable zooming.
  378.     picCanvas.MousePointer = vbCrosshair
  379.     DrawingMode = MODE_START_ZOOM
  380. End Sub
  381. ' If we are zooming, start the rubberband hex.
  382. Private Sub picCanvas_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  383.     Select Case DrawingMode
  384.         Case MODE_START_ZOOM
  385.             ' Start a zooming rubberband hex.
  386.             DrawingMode = MODE_ZOOMING
  387.         
  388.             OldMode = picCanvas.DrawMode
  389.             picCanvas.DrawMode = vbInvert
  390.             
  391.             StartX = X
  392.             StartY = Y
  393.             LastX = X
  394.             LastY = Y
  395.             picCanvas.Line (StartX, StartY)-(LastX, LastY), , B
  396.         
  397.         Case MODE_NONE
  398.             ' Select a hex.
  399.             Dim oldcolor As Long
  400.             ' Unhighlight the previous hex.
  401.             If Not Selectedhex Is Nothing Then
  402.                 Selectedhex.Highlighted = False
  403.                 Selectedhex.Draw picCanvas
  404.             End If
  405.             ' Find the selected hex.
  406.             Set Selectedhex = ObjectAt(X, Y)
  407.             ' Highlight the selected hex.
  408.             If Not Selectedhex Is Nothing Then
  409.                 Selectedhex.Highlighted = True
  410.                 Selectedhex.Draw picCanvas
  411.             End If
  412.     End Select
  413. End Sub
  414. ' If we are zooming, continue the rubberband hex.
  415. Private Sub picCanvas_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
  416.     If DrawingMode <> MODE_ZOOMING Then Exit Sub
  417.     ' Erase the old hex.
  418.     picCanvas.Line (StartX, StartY)-(LastX, LastY), , B
  419.     ' Draw the new hex.
  420.     LastX = X
  421.     LastY = Y
  422.     picCanvas.Line (StartX, StartY)-(LastX, LastY), , B
  423. End Sub
  424. ' If we are zooming, finish the rubberband hex.
  425. Private Sub picCanvas_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
  426. Dim wid As Single
  427. Dim hgt As Single
  428. Dim mid As Single
  429.     If DrawingMode <> MODE_ZOOMING Then Exit Sub
  430.     DrawingMode = MODE_NONE
  431.     ' Erase the old hex.
  432.     picCanvas.Line (StartX, StartY)-(LastX, LastY), , B
  433.     LastX = X
  434.     LastY = Y
  435.     ' We're done drawing for this rubberband hex.
  436.     picCanvas.DrawMode = OldMode
  437.     picCanvas.MousePointer = vbDefault
  438.     ' Set the new world window bounds.
  439.     If StartX > LastX Then
  440.         Wxmin = LastX
  441.         Wxmax = StartX
  442.     Else
  443.         Wxmin = StartX
  444.         Wxmax = LastX
  445.     End If
  446.     If StartY > LastY Then
  447.         Wymin = LastY
  448.         Wymax = StartY
  449.     Else
  450.         Wymin = StartY
  451.         Wymax = LastY
  452.     End If
  453.     ' Set the new world window bounds.
  454.     SetWorldWindow
  455. End Sub
  456. Private Sub picCanvas_Paint()
  457. Dim obj As Hex
  458.     MousePointer = vbHourglass
  459.     DoEvents
  460.     ' Make the Hexes draw themselves.
  461.     For Each obj In Hexes
  462.         obj.Draw picCanvas
  463.     Next obj
  464.     MousePointer = vbDefault
  465. End Sub
  466. ' Move the world window.
  467. Private Sub VScrollBar_Change()
  468.     If IgnoreSbarChange Then Exit Sub
  469.     VScrollBarChanged
  470. End Sub
  471.